package com.leo.foodmaster.admin.purchase.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leo.foodmaster.admin.purchase.entity.PurchaseBill;
import com.leo.foodmaster.admin.purchase.entity.PurchaseBillDetails;
import com.leo.foodmaster.admin.purchase.mapper.PurchaseBillMapper;
import com.leo.foodmaster.admin.purchase.service.IPurchaseBillDetailsService;
import com.leo.foodmaster.admin.purchase.service.IPurchaseBillService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leo.foodmaster.admin.system.entity.UserBean;
import com.leo.foodmaster.commons.constants.RecordStatus;
import com.leo.foodmaster.commons.entity.Result;
import com.leo.foodmaster.commons.util.WebUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 采购单 服务实现类
 * </p>
 *
 * @author Leo
 * @since 2021-08-01
 */
@Service
@AllArgsConstructor
public class PurchaseBillServiceImpl extends ServiceImpl<PurchaseBillMapper, PurchaseBill> implements IPurchaseBillService {
    private final IPurchaseBillDetailsService purchaseBillDetailsService;

    /**
     * 条件分页查询采购清单
     * @param page 分页参数
     * @param serialNum 采购单编号
     * @param supplierId 供应商Id
     * @param statusList 审核状态
     * @param paymentType 支付类型
     * @param payStatus 支付状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<PurchaseBill>
     */
    @Override
    public IPage<PurchaseBill> getPurchaseBillPageList(Page<PurchaseBill> page, String serialNum, Long supplierId,
                                                       List<String> statusList, String paymentType, String payStatus,
                                                       String beginTime, String endTime) {
        Long loginOrganId = WebUtils.getUser().getOrganId();
        LambdaQueryWrapper<PurchaseBill> qw = Wrappers.lambdaQuery(PurchaseBill.class)
                .eq(PurchaseBill::getOrganId, loginOrganId)
                .like(StrUtil.isNotBlank(serialNum), PurchaseBill::getSerialNum, serialNum)
                .eq(BeanUtil.isNotEmpty(supplierId), PurchaseBill::getSupplierId, supplierId)
                .in(BeanUtil.isNotEmpty(statusList), PurchaseBill::getStatus, statusList)
                .eq(StrUtil.isNotBlank(paymentType), PurchaseBill::getPaymentType, paymentType)
                .eq(StrUtil.isNotBlank(payStatus), PurchaseBill::getPayStatus, payStatus)
                .ge(StrUtil.isNotBlank(beginTime), PurchaseBill::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), PurchaseBill::getCreateTime, endTime);
        Page<PurchaseBill> pageList = page(page, qw);
        List<PurchaseBill> records = pageList.getRecords();
        if (!records.isEmpty()) {
            for (PurchaseBill purchaseBill : records) {
                List<PurchaseBillDetails> details = purchaseBillDetailsService.list(Wrappers.lambdaQuery(PurchaseBillDetails.class)
                        .eq(PurchaseBillDetails::getPurchaseBillId, purchaseBill.getId()));
                purchaseBill.setDetailList(details);
            }
        }
        return pageList;
    }

    /**
     * 新增采购清单
     * @param purchaseBill 采购清单
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> addPurchaseBill(PurchaseBill purchaseBill) {
        UserBean user = WebUtils.getUser();

        // 新增采购单
        purchaseBill.setOrganId(user.getOrganId());
        purchaseBill.setSerialNum("CG-" + System.currentTimeMillis());
        purchaseBill.setStatus(RecordStatus.UNCHECKED);
        purchaseBill.setCreator(user.getName());
        purchaseBill.setCheckTime(LocalDateTime.now());
        save(purchaseBill);

        // 新增采购清单详情
        List<PurchaseBillDetails> detailList = purchaseBill.getDetailList();
        detailList.forEach(detail -> {
            detail.setPurchaseBillId(purchaseBill.getId());
            detail.setSupplier(purchaseBill.getSupplier());
            detail.setSupplierId(purchaseBill.getSupplierId());
            detail.setSupplierOrganId(purchaseBill.getSupplierOrganId());
            detail.setCreator(user.getName());
            detail.setCreateTime(LocalDateTime.now());
        });
        purchaseBillDetailsService.saveBatch(detailList);

        return Result.success();
    }

    /**
     * 修改采购清单
     * @param purchaseBill 采购清单
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updatePurchaseBill(PurchaseBill purchaseBill) {
        UserBean user = WebUtils.getUser();
        // 只有未审核和审核不通过才能修改
        if (RecordStatus.CHECK_PASS.equals(purchaseBill.getStatus())) {
            return Result.fail("该采购清单已审核，不能修改！");
        }
        // 修改之后采购单的状态改为待审核
        purchaseBill.setStatus(RecordStatus.UNCHECKED);
        purchaseBill.setUpdateUser(user.getName());
        purchaseBill.setUpdateTime(LocalDateTime.now());
        // 修改采购单
        updateById(purchaseBill);
        // 修改采购单详情
        List<PurchaseBillDetails> detailList = purchaseBill.getDetailList();
        detailList.forEach(item -> {
            item.setUpdateUser(user.getName());
            item.setUpdateTime(LocalDateTime.now());
        });
        purchaseBillDetailsService.updateBatchById(detailList);
        return Result.success();
    }

    /**
     * 删除采购清单
     * @param id 采购单Id
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> deletePurchaseBill(Long id) {
        // 只有未审核和审核不通过的清单才能删除
        PurchaseBill purchaseBill = getById(id);
        if (RecordStatus.CHECK_PASS.equals(purchaseBill.getStatus())) {
            return Result.fail("该采购清单已审核，不能删除！");
        }
        // 删除采购详细列表
        boolean remove = purchaseBillDetailsService.remove(Wrappers.lambdaUpdate(PurchaseBillDetails.class)
                .eq(PurchaseBillDetails::getPurchaseBillId, id));
        if (remove) {
            // 删除采购清单
            removeById(id);
        }
        return Result.success();
    }

    /**
     * 审核采购清单
     * @param purchaseBill 采购清单
     * @return Result<Object>
     */
    @Override
    public Result<Object> checkPurchaseBill(PurchaseBill purchaseBill) {
        UserBean user = WebUtils.getUser();
        purchaseBill.setCheckBy(user.getName());
        purchaseBill.setCheckById(user.getId());
        purchaseBill.setUpdateUser(user.getName());
        purchaseBill.setUpdateTime(LocalDateTime.now());
        updateById(purchaseBill);
        return Result.success();
    }

    /**
     * 根据采购清单Id查询采购单详情
     * @param id 采购单Id
     * @return PurchaseBill
     */
    @Override
    public PurchaseBill getPurchaseBillById(Long id) {
        PurchaseBill purchaseBill = getById(id);
        List<PurchaseBillDetails> list = purchaseBillDetailsService.list(Wrappers.lambdaQuery(PurchaseBillDetails.class)
                .eq(PurchaseBillDetails::getPurchaseBillId, id));
        purchaseBill.setDetailList(list);
        return purchaseBill;
    }

    /**
     * 条件查询采购清单列表
     * @param serialNum 采购单号
     * @param supplierId 供应商Id
     * @param statusList 状态列表
     * @param paymentType 支付类型
     * @param payStatus 支付状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return 结果
     */
    @Override
    public List<PurchaseBill> getFoodMaterialList(String serialNum, Long supplierId, List<String> statusList, String paymentType, String payStatus, String beginTime, String endTime) {
        Long loginOrganId = WebUtils.getUser().getOrganId();
        LambdaQueryWrapper<PurchaseBill> qw = Wrappers.lambdaQuery(PurchaseBill.class)
                .eq(PurchaseBill::getOrganId, loginOrganId)
                .like(StrUtil.isNotBlank(serialNum), PurchaseBill::getSerialNum, serialNum)
                .eq(BeanUtil.isNotEmpty(supplierId), PurchaseBill::getSupplierId, supplierId)
                .in(BeanUtil.isNotEmpty(statusList), PurchaseBill::getStatus, statusList)
                .eq(StrUtil.isNotBlank(paymentType), PurchaseBill::getPaymentType, paymentType)
                .eq(StrUtil.isNotBlank(payStatus), PurchaseBill::getPayStatus, payStatus)
                .ge(StrUtil.isNotBlank(beginTime), PurchaseBill::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), PurchaseBill::getCreateTime, endTime);
        return list(qw);
    }
}
